/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package almacenamiento;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
/**
 *
 * @author Fernando
 */
public class EjercicioCatalogo {
    static Scanner sc = new Scanner(System.in);
   static String Archivo ="Tablas.dat";
   static  Catalogo catalogo = new Catalogo(Archivo);
    
    static void Ejemplo(){
    String archivo ="jejeje.dat";
    Catalogo c = new Catalogo(archivo);
    
    List<Atributo> attrs = new ArrayList<Atributo>();
    attrs.add(new Atributo("character", Character.class));
    attrs.add(new Atributo("byte", Byte.class));
    attrs.add(new Atributo("short", Short.class));
    attrs.add(new Atributo("integer", Integer.class));
    attrs.add(new Atributo("long", Long.class));
    attrs.add(new Atributo("float", Float.class));
    attrs.add(new Atributo("double", Double.class));
    attrs.add(new Atributo("string", String.class));
   
    Tabla tabla1 = new Tabla("tabla1", attrs);
    Tabla tabla2 = new Tabla("tabla2", attrs);
    Tabla tabla3 = new Tabla("tabla3", attrs);

    EntradaCatalogo ec1 = new EntradaCatalogo(tabla1, archivo) ;
    EntradaCatalogo ec2 = new EntradaCatalogo(tabla2, archivo) ;
    EntradaCatalogo ec3 = new EntradaCatalogo(tabla3, archivo) ;

    c.crearNuevaEntrada(ec1);
    c.crearNuevaEntrada(ec2);
    c.crearNuevaEntrada(ec3);
    
    System.out.println(c);
    
    c.EliminarEntrada(ec3);
    System.out.println("eliminando una entrada");
    System.out.println(c);
    
    }
    static void Menu(){
        System.out.println("");
        System.out.println("");
        System.out.println("**************************************************");
        System.out.println("*            EJERCICIO CON CATALOGOS             *");
        System.out.println("**************************************************");
        System.out.println("");
        System.out.println("1.- Agregar Tabla");
        System.out.println("2.- Modificar Tabla");
        System.out.println("3.- Eliminar Tabla");
        System.out.println("4.- Ver todas las tablas"); 
        System.out.println("5.- Salir");
        System.out.print("                         Escriba una opciÃ³n: ");
    }
    static void MenuAtributos(){
        System.out.println("Escoja un tipo para este atributo:");
        System.out.println("1.- Caracter");
        System.out.println("2.- Byte");
        System.out.println("3.- Short");
        System.out.println("4.- Integer"); 
        System.out.println("5.- Long");
        System.out.println("6.- Float");
        System.out.println("7.- Double");
        System.out.println("8.- String");
        System.out.println("9.- Salir");
        System.out.print("                   Escriba una opciÃ³n: ");
    }
    static void MenuAtributoss(){
        System.out.println("Escoja un tipo para este atributo:");
        System.out.println("1.- Caracter");
        System.out.println("2.- Byte");
        System.out.println("3.- Short");
        System.out.println("4.- Integer"); 
        System.out.println("5.- Long");
        System.out.println("6.- Float");
        System.out.println("7.- Double");
        System.out.println("8.- String");
        System.out.print("                   Escriba una opciÃ³n: ");
    }
   static void MenuAtributosModificar(){
        System.out.println("Escoja una de las siguientes opciones para esta tabla:");
        System.out.println("1.- Eliminar atributo");
        System.out.println("2.- Cambiar nombre atributo");
        System.out.println("3.- Cambiar tipo atributo");
        System.out.println("4.- Agregar atributo"); 
        System.out.println("5.- Salir");
        System.out.print("                   Escriba una opciÃ³n: ");
    }
   
    static void AgregarTabla(){
        //nombre de tabla y para los atributos
        System.out.println("**************************************************");
        System.out.println("*              AGREGAR NUEVA TABLA               *");
        System.out.println("**************************************************");
        System.out.println("");
        System.out.print("Escriba el nombre de Tabla: ");
        String nombreTabla = sc.next();
        String nombreAtributo= "";
        boolean continuar = true;
        int opcion = 0;
        String entrada="";
        List<Atributo> attrs = new ArrayList<Atributo>();
        while (continuar){
            int cont = attrs.size()+1;
            System.out.println("");
            System.out.print("Escriba el nombre del atributo  " + cont +" para "+nombreTabla+":  ");
            nombreAtributo = sc.next();
            MenuAtributos();   
            entrada = sc.next();
            opcion = RecuperarOpcion(entrada);
            switch(opcion){
                case 1://char
                    attrs.add(new Atributo(nombreAtributo, Character.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Caracter");
                    break;
                case 2: //byte
                    attrs.add(new Atributo(nombreAtributo, Byte.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Byte");
                    break;
                case 3: //short
                    attrs.add(new Atributo(nombreAtributo, Short.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Short");
                    break;
                case 4: //interger
                    attrs.add(new Atributo(nombreAtributo, Integer.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Integer");
                    break;
                case 5: //long
                    attrs.add(new Atributo(nombreAtributo, Long.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Long");
                    break;
                case 6: //float
                    attrs.add(new Atributo(nombreAtributo, Float.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Float");
                    break;
                case 7: //double
                    attrs.add(new Atributo(nombreAtributo, Double.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Double");
                    break;
                case 8: //string
                    attrs.add(new Atributo(nombreAtributo, String.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  String");
                    break;
                case 9://salir
                    System.out.println("UD. agregÃ³ una nueva tabla.....");
                    catalogo.crearNuevaEntrada(new EntradaCatalogo(new  Tabla(nombreTabla, attrs),Archivo));
                    //tenemos que serializar
                    SerializacionCatalogo();
                    continuar = ! continuar;
                    break;
                default:
                    System.out.println("Seleccione una opciÃ³n correcta...");
                    break;
            }
        }
    }
    static boolean SerializacionCatalogo(){
                boolean listo =true;
                //iniciar el proceso de serializacion
                 try {//colocar los obejtos en el disco
                     //creamos el archivo
                     FileOutputStream fs = new FileOutputStream(Archivo);
                     //Esta clase tiene el metodo writeObject()  ...
                     ObjectOutputStream os = new ObjectOutputStream(fs );             
                     os.writeObject(catalogo);        
                     os.close();
                 }  catch (Exception e) {
                     listo = false;
                 }
                 return listo;
    }
    static boolean DeserializarCatalogo(){
         boolean listo =true;
         //iniciar el proceso de serializacion
         try { //recuperamos un archivo del disco
             FileInputStream fis = new FileInputStream(Archivo);
             //Esta clase tiene el metodo writeObject()  ...
             ObjectInputStream ois = new ObjectInputStream(fis);             
             Object aux = ois.readObject();
            // Mientras haya objetos
            while (aux!=null) {
                if (aux instanceof Catalogo) {
                     catalogo =(Catalogo)aux;
                 }   
                aux = ois.readObject();
            }
             ois.close();             
         }  catch (EOFException e1)
            {
    ///        System.out.println ("Fin de fichero");
         }
        catch (Exception e2)
        {
            listo = false;
        }
                return listo;
        }
    static EntradaCatalogo EliminarAtributo(EntradaCatalogo ec){
        System.out.println("**************************************************");
        System.out.println("*Eliminar atributo de la tabla " + ec.getNombreTabla()+"  ");
        System.out.println("**************************************************");
        System.out.println("");
            List<Atributo> atributos = ec.getTabla().getAtributos();
            for (int i = 0; i < atributos.size(); i++) {
                System.out.println(atributos.get(i));
            }
            System.out.println("Escriba el nombre del atributo a eliminar: ");
            String at = sc.next();
            for (int i = 0; i < atributos.size(); i++) {
                if(atributos.get(i).getNombre().compareTo(at)==0)
                    atributos.remove(i);
           }
            EntradaCatalogo e = new EntradaCatalogo(new Tabla(ec.getNombreTabla(),atributos),ec.getNombreArchivo());
            return e;
    }
    static EntradaCatalogo CambiarNombreAtributo(EntradaCatalogo ec){
        System.out.println("**************************************************");
        System.out.println("*Cambiar el nombre de un atributo de la tabla " + ec.getNombreTabla()+"  ");
        System.out.println("**************************************************");
        System.out.println("");
            List<Atributo> atributos = ec.getTabla().getAtributos();
            for (int i = 0; i < atributos.size(); i++) {
                System.out.println(atributos.get(i));
            }
            System.out.print("Escriba el nombre del atributo a cambiar: ");
            String at = sc.next();
            
            System.out.print("Escriba el nuevo nombre: ");
            String ata = sc.next();
            
            for (int i = 0; i < atributos.size(); i++) {
                if(atributos.get(i).getNombre().compareTo(at)==0) {
                    atributos.get(i).setNombre(ata);
                }
           }
            System.out.println("Nombre cambiado correctamente");
            EntradaCatalogo e = new EntradaCatalogo(new Tabla(ec.getNombreTabla(),atributos),ec.getNombreArchivo());
            return e;
    }
    static EntradaCatalogo CambiarTipoAtributo(EntradaCatalogo ec){
          System.out.println("**************************************************");
        System.out.println("*Cambiar el tipo de un atributo de la tabla " + ec.getNombreTabla()+"  ");
        System.out.println("**************************************************");
        System.out.println("");
            List<Atributo> atributos = ec.getTabla().getAtributos();
            for (int i = 0; i < atributos.size(); i++) {
                System.out.println(atributos.get(i));
            }
            System.out.print("Escriba el nombre del atributo: ");
            String nombreAtributo = sc.next();
            
                       
            int k =0;
            for (int i = 0; i < atributos.size(); i++) {
                if(atributos.get(i).getNombre().compareTo(nombreAtributo)==0) {
                    k =i;
                    atributos.remove(i);
                }
           }
            
           boolean continuar = true;
            int opcion = 0;
            String entrada="";
        while (continuar){
            System.out.println("");
            MenuAtributoss();   
            entrada = sc.next();
            opcion = RecuperarOpcion(entrada);
            switch(opcion){
                case 1://char
                    atributos.set(k, new Atributo(nombreAtributo, Character.class));
                    continuar = ! continuar;
                    break;
                case 2: //byte
                    atributos.set(k, new Atributo(nombreAtributo, Byte.class));
                    continuar = ! continuar;
                    break;
                case 3: //short
                    atributos.set(k, new Atributo(nombreAtributo, Short.class));
                    continuar = ! continuar;
                    break;
                case 4: //interger
                    atributos.set(k, new Atributo(nombreAtributo, Integer.class));
                    continuar = ! continuar;
                    break;
                case 5: //long
                    atributos.set(k, new Atributo(nombreAtributo, Long.class));
                    continuar = ! continuar;
                    break;
                case 6: //float
                    atributos.set(k, new Atributo(nombreAtributo, Float.class));
                    continuar = ! continuar;
                    break;
                case 7: //double
                    atributos.set(k, new Atributo(nombreAtributo, Double.class));
                    continuar = ! continuar;
                    break;
                case 8: //string
                    atributos.set(k, new Atributo(nombreAtributo, String.class));
                    continuar = ! continuar;
                    break;
                default:
                    System.out.println("Seleccione una opciÃ³n correcta...");
                    break;
            }
        }
            
            
            
            System.out.println("Tipo cambiado correctamente");
            EntradaCatalogo e = new EntradaCatalogo(new Tabla(ec.getNombreTabla(),atributos),ec.getNombreArchivo());
            return e;
    }
    static EntradaCatalogo AgregarAtributo(EntradaCatalogo ec){
        System.out.println("**************************************************");
        System.out.println("*Agregar atributos a la tabla " + ec.getNombreTabla()+"  ");
        System.out.println("**************************************************");
        System.out.println("");
            
        List<Atributo> atributos = ec.getTabla().getAtributos();
            for (int i = 0; i < atributos.size(); i++) {
                System.out.println(atributos.get(i));
            }
            System.out.print("Escriba el nombre del atributo a agregar: ");
            String nombreAtributo =sc.next();
             boolean continuar = true;
            int opcion = 0;
            String entrada="";
        while (continuar){
            System.out.println("");
            MenuAtributoss();   
            entrada = sc.next();
            opcion = RecuperarOpcion(entrada);
            switch(opcion){
                case 1://char
                   atributos.add(new Atributo(nombreAtributo, Character.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Caracter");
                    continuar = ! continuar;
                    break;
                case 2: //byte
                    atributos.add(new Atributo(nombreAtributo, Byte.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Byte");
                    continuar = ! continuar;
                    break;
                case 3: //short
                    atributos.add(new Atributo(nombreAtributo, Short.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Short");
                    continuar = ! continuar;
                    break;
                case 4: //interger
                    atributos.add(new Atributo(nombreAtributo, Integer.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Integer");
                    continuar = ! continuar;
                    break;
                case 5: //long
                    atributos.add(new Atributo(nombreAtributo, Long.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Long");
                    continuar = ! continuar;
                    break;
                case 6: //float
                    atributos.add(new Atributo(nombreAtributo, Float.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Float");
                    continuar = ! continuar;
                    break;
                case 7: //double
                    atributos.add(new Atributo(nombreAtributo, Double.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  Double");
                    continuar = ! continuar;
                    break;
                case 8: //string
                    atributos.add(new Atributo(nombreAtributo, String.class));
                    System.out.println("Atributo: " +nombreAtributo+ "     Tipo:  String");
                    continuar = ! continuar;
                    break;
                default:
                    System.out.println("Seleccione una opciÃ³n correcta...");
                    break;
            }
        }
            
            System.out.println("UD. agregÃ³ un nuev atributo para esta tabla.....");
            EntradaCatalogo e = new EntradaCatalogo(new Tabla(ec.getNombreTabla(),atributos),ec.getNombreArchivo());
            return e;
    }
    static void ModificarTabla(){
        System.out.println("**************************************************");
        System.out.println("*               MODIFICAR TABLAS                 *");
        System.out.println("**************************************************");
        System.out.println("");
        DeserializarCatalogo();
        Map<String, EntradaCatalogo> entradas = catalogo.getEntradas();
        Collection<EntradaCatalogo> values = entradas.values();
        System.out.println("Nro de tablas: " + catalogo.getNumeroDeTablas());
        for (Iterator<EntradaCatalogo> it = values.iterator(); it.hasNext();) {
            EntradaCatalogo entradaCatalogo = it.next();
            System.out.println(entradaCatalogo.getNombreTabla() +"  "+ entradaCatalogo.getTabla());
        }
        if (catalogo.getNumeroDeTablas() > 0){
        System.out.print("Escriba el nombre de la tabla a modificar: ");
        String nombretabla = sc.next();        
        EntradaCatalogo ec = entradas.get(nombretabla);
            int opcion = 0;
        String entrada="";
        boolean continuar = true;
        while (continuar){
            MenuAtributosModificar();   
            entrada = sc.next();
            opcion = RecuperarOpcion(entrada);
            switch(opcion){
                case 1://Eliminar Atributo
                    ec = EliminarAtributo(ec);
                    break;
                case 2: //cambiar nombre atributo
                    ec = CambiarNombreAtributo(ec);
                    break;
                case 3: //cambiar tipo de atributo
                    ec = CambiarTipoAtributo(ec);
                    break;
                case 4: //agregar nuevo atributo
                    ec = AgregarAtributo(ec);
                    break;
                case 5://salir
                    System.out.println("SE MODIFICÃ“ LA TABLA...");
                    catalogo.ActualizarEntrada(ec);
                    SerializacionCatalogo();
                    continuar = ! continuar;
                    break;
                default:
                    System.out.println("Seleccione una opciÃ³n correcta");
                    break;
            }
            }
        }
        else {
            System.out.println("No se puede modificar ninguna tabla...");
        }
    }
    static void EliminarTabla(){
        System.out.println("**************************************************");
        System.out.println("*               ELIMINAR TABLA                   *");
        System.out.println("**************************************************");
        System.out.println("");
        DeserializarCatalogo();
        Map<String, EntradaCatalogo> entradas = catalogo.getEntradas();
        Collection<EntradaCatalogo> values = entradas.values();
        System.out.println("Nro de tablas: " + catalogo.getNumeroDeTablas());
     
        for (Iterator<EntradaCatalogo> it = values.iterator(); it.hasNext();) {
            EntradaCatalogo entradaCatalogo = it.next();
            System.out.println(entradaCatalogo.getNombreTabla() +"  "+ entradaCatalogo.getTabla());
        }
        System.out.print("Escriba el nombre de la tabla a eliminar: ");
        String nombretabla = sc.next();        
        EntradaCatalogo ec = entradas.get(nombretabla);
        catalogo.EliminarEntrada(ec);
        SerializacionCatalogo();      
        System.out.println("Tabla eliminada...");   
        System.out.println("---------------------------------------------------");
        System.out.println("---------------------------------------------------");
    }
    
    static void ListarTablas(){
        System.out.println("**************************************************");
        System.out.println("*                 LISTAR TABLAS                  *");
        System.out.println("**************************************************");
        System.out.println("");
        DeserializarCatalogo();
        Map<String, EntradaCatalogo> entradas = catalogo.getEntradas();
        Collection<EntradaCatalogo> values = entradas.values();
        System.out.println("Nro de tablas: " + catalogo.getNumeroDeTablas());
     
        for (Iterator<EntradaCatalogo> it = values.iterator(); it.hasNext();) {
            EntradaCatalogo entradaCatalogo = it.next();
            System.out.println(entradaCatalogo.getNombreTabla() +"  "+ entradaCatalogo.getTabla());
        }
        //System.out.println(catalogo);
        System.out.println("---------------------------------------------------");
        System.out.println("---------------------------------------------------");
    }
    static int RecuperarOpcion(String entrada){
        int r = -9;
        try {
            r = Integer.parseInt(entrada);
            
        } catch (Exception e) {
            r = -1;
        }
        return r;
    }
    
    public static void main(String args[]) {
        try {
        int opcion = 0;
        String entrada="";
        boolean continuar = true;
        //System.out.println("Hola Javier    " + entrada);
        while (continuar){
         Menu();   
        entrada = sc.next();
        opcion = RecuperarOpcion(entrada);
            switch(opcion){
                case 1://agregar tabla
                    AgregarTabla();
                    break;
                case 2: //modificar tabla
                    ModificarTabla();
                    break;
                case 3: // Eliminar tabla
                    EliminarTabla();
                    break;
                case 4: // listar todas las tablas
                    ListarTablas();
                    break;
                case 5://salir
                    System.out.println("UD. SALIÃ“ DEL PROGRAMA.....");
                    continuar = ! continuar;
                    break;
                default:
                    System.out.println("Seleccione una opciÃ³n correcta");
                    break;
            }
            
        }    
        } catch (Exception e) {
        }
    }
}
